#pragma once

#include "coro/concepts/awaitable.hpp"
#include "coro/fd.hpp"

#ifdef CPPCORO_FEATURE_NETWORKING
    #include "coro/epoll.hpp"
    #include "coro/task.hpp"
#endif // #ifdef CPPCORO_FEATURE_NETWORKING

#include <chrono>
#include <concepts>
#include <coroutine>

namespace coro::concepts
{

template<typename type>
concept executor = requires(type t, std::coroutine_handle<> c)
{
    { t.schedule() } -> coro::concepts::awaiter;
    { t.yield() } -> coro::concepts::awaiter;
    { t.resume(c) } -> std::same_as<void>;
};

#ifdef CPPCORO_FEATURE_NETWORKING
template<typename type>
concept io_exceutor = executor<type> and requires(type t, std::coroutine_handle<> c, fd_t fd, coro::epoll_op op, std::chrono::milliseconds timeout)
{
    { t.epoll(fd, op, timeout) } -> std::same_as<coro::task<epoll_status>>;
};
#endif // #ifdef CPPCORO_FEATURE_NETWORKING


} // namespace coro::concepts